using System;
using System.Collections.Generic;
using System.Text;
using System.Data.Common;
using System.Data;
using Sinacor.Infra.Service.Data;
using Sinacor.Infra.Service.Security.Authorization;
using Sinacor.Infra.Service.Common;

namespace Sinacor.Servico.Bovespa.Corretagem.ResourceAccess
{

    /// <summary>
    /// Business Logic DescontoDiferenciado
    /// </summary>
    public class DescontoDiferenciado : BaseResourceAccess
    {
        #region Construtor

        /// <summary>
        /// Construtor padrão
        /// </summary>
        public DescontoDiferenciado()
            : base(AuthorizationContext.Current.CompanyId)
        {
        }

        #endregion

        #region ConsultarDescontoDiferenciado
        /// <summary>
        /// Método ConsultarDescontoDiferenciado
        /// </summary>
        public List<BusinessEntity.DescontoDiferenciado> ConsultarDescontoDiferenciado(BusinessEntity.Parameter.ConsultarDescontoDiferenciado consultardescontodiferenciado)
        {
            List<BusinessEntity.DescontoDiferenciado> response = null;
            StringBuilder sql = new StringBuilder();

            sql.Append(@"select tbocorr_poli_desc.cd_tabela,
							nvl(tbocorr_poli_desc.pc_redacr, 0) pc_redacr, 
							tbocorr_tipo_desc.in_tipo_desc, 
							tbocorr_tipo_desc.ds_tipo_desc,
							tbocorr_tipo_desc.in_inf_obrig
							from 
							tbocorr_poli_desc, tbocorr_tipo_desc
							where tbocorr_poli_desc.in_tipo_desc = tbocorr_tipo_desc.in_tipo_desc
							and cd_tabela = :CD_TABELA");

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sql.ToString()))
            {
                this.DataBase.AddInParameter(command, "CD_TABELA", DbType.Int32, consultardescontodiferenciado.CodigoTabelaPadrao);

                response = this.FindAll<BusinessEntity.DescontoDiferenciado>(command, new ConstructEntity<BusinessEntity.DescontoDiferenciado>(ConstrutorConsultarDescontoDiferenciado));
            }

            return response;
        }

        #endregion

        #region ConstrutorConsultarDescontoDiferenciado
        protected BusinessEntity.DescontoDiferenciado ConstrutorConsultarDescontoDiferenciado(IDataReader reader)
        {
            BusinessEntity.DescontoDiferenciado entity = new BusinessEntity.DescontoDiferenciado();

            entity.CodigoTabela = reader.GetValue<System.Int32>("cd_tabela");
            entity.Percentual = reader.GetValue<System.Decimal>("pc_redacr");
            entity.TipoDesconto.Codigo = reader.GetValue<System.Int32>("in_tipo_desc");
            entity.TipoDesconto.Descricao = reader.GetValue<System.String>("ds_tipo_desc");
            entity.TipoDesconto.Obrigatorio = (reader.GetValue<System.String>("in_inf_obrig").ToUpper() == "S") ? true : false;            

            return entity;
        }
        #endregion

        #region ConsultarTipoDescontoDiferenciado
        /// <summary>
        /// Método ConsultarTipoDescontoDiferenciado
        /// </summary>
        public List<BusinessEntity.TipoDescontoDiferenciado> ConsultarTipoDescontoDiferenciado()
        {
            List<BusinessEntity.TipoDescontoDiferenciado> response = null;
            StringBuilder sql = new StringBuilder();

            sql.Append(@"select in_tipo_desc, 
							ds_tipo_desc, 
							in_inf_obrig 
							from tbocorr_tipo_desc
							");

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sql.ToString()))
            {

                response = this.FindAll<BusinessEntity.TipoDescontoDiferenciado>(command, new ConstructEntity<BusinessEntity.TipoDescontoDiferenciado>(ConstrutorConsultarTipoDescontoDiferenciado));
            }

            return response;
        }

        #endregion

        #region ConstrutorConsultarTipoDescontoDiferenciado
        protected BusinessEntity.TipoDescontoDiferenciado ConstrutorConsultarTipoDescontoDiferenciado(IDataReader reader)
        {
            BusinessEntity.TipoDescontoDiferenciado entity = new BusinessEntity.TipoDescontoDiferenciado();

            entity.Codigo = reader.GetValue<System.Int32>("in_tipo_desc");
            entity.Descricao = reader.GetValue<System.String>("ds_tipo_desc");
            entity.Obrigatorio = (reader.GetValue<System.String>("in_inf_obrig").ToUpper() == "S") ? true: false;            
            return entity;
        }
        #endregion

        #region ExcluirDescontoDiferenciado
        /// <summary>
        /// Método ExcluirDescontoDiferenciado
        /// </summary>
        public void ExcluirDescontoDiferenciado(BusinessEntity.Parameter.ExcluirDescontoDiferenciado excluirdescontodiferenciado)
        {
            StringBuilder sql = new StringBuilder();

            sql.Append(@"delete from TBOCORR_POLI_DESC 
							where cd_tabela = :CD_TABELA");

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sql.ToString()))
            {
                this.DataBase.AddInParameter(command, "CD_TABELA", DbType.Int32, excluirdescontodiferenciado.CodigoTabelaPadrao);

                this.DataBase.ExecuteNonQuery(command);

            }


        }

        #endregion

        #region SalvarDescontoDiferenciado
        /// <summary>
        /// Método SalvarDescontoDiferenciado
        /// </summary>
        public void SalvarDescontoDiferenciado(BusinessEntity.DescontoDiferenciado descontodiferenciado)
        {
            StringBuilder sql = new StringBuilder();

            sql.Append(@"insert into TBOCORR_POLI_DESC 
							(cd_tabela, in_tipo_desc, pc_redacr)
							values
							(:CD_TABELA,
							:IN_TIPO_DESC,
							:PC_REDACR)");

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sql.ToString()))
            {
                this.DataBase.AddInParameter(command, "CD_TABELA", DbType.Int32, descontodiferenciado.CodigoTabela);
                this.DataBase.AddInParameter(command, "IN_TIPO_DESC", DbType.Int32, descontodiferenciado.TipoDesconto.Codigo);
                this.DataBase.AddInParameter(command, "PC_REDACR", DbType.Decimal, descontodiferenciado.Percentual);

                this.DataBase.ExecuteNonQuery(command);

            }


        }

        public void SalvarDescontoDiferenciado(List<BusinessEntity.DescontoDiferenciado> descontodiferenciado)
        {
            foreach (BusinessEntity.DescontoDiferenciado item in descontodiferenciado)
            {
                SalvarDescontoDiferenciado(item);
            }
        }

        #endregion

        #region ConsultarDescontosDiferenciados

        /// <summary>
        /// Consultar descontos diferenciados
        /// </summary>
        /// <param name="parameter">Parâmetro para consultar descontos diferenciados</param>
        /// <returns>Lista de DescontoDiferenciado</returns>
        public List<BusinessEntity.DescontoDiferenciado> ConsultarDescontosDiferenciados(BusinessEntity.Parameter.FiltroDescontoDiferenciado parameter)
        {
            List<BusinessEntity.DescontoDiferenciado> listaDescontos = null;
            List<BusinessEntity.TipoDescontoDiferenciado> listaTiposDescontos = null;
            StringBuilder sql = new StringBuilder();

            #region Consultar a lista de tipos de descontos diferenciados

            listaTiposDescontos = new TipoDescontoDiferenciado().ConsultarTiposDescontosDiferenciados(new BusinessEntity.Parameter.FiltroTipoDescontoDiferenciado());

            #endregion

            using (DbCommand command = this.DataBase.GetSqlStringCommand(" "))
            {
                sql.AppendLine("SELECT");
                sql.AppendLine("    CD_TABELA Codigo,");
                sql.AppendLine("    IN_TIPO_DESC CodigoTipoDesconto,");
                sql.AppendLine("    PC_REDACR Percentual");
                sql.AppendLine("FROM");
                sql.AppendLine("    TBOCORR_POLI_DESC");
                sql.AppendLine("WHERE 1 = 1");
                
                //Filtros opcionais
                if (parameter.CodigoTabela.HasValue)
                {
                    sql.AppendLine("AND CD_TABELA = :Codigo");
                    this.DataBase.AddInParameter(command, "Codigo", DbType.Int32, parameter.CodigoTabela);
                }

                if (parameter.TipoDesconto != null && parameter.TipoDesconto.Codigo != null)
                {
                    sql.AppendLine("AND IN_TIPO_DESC = :CodigoTipoDesconto");
                    this.DataBase.AddInParameter(command, "CodigoTipoDesconto", DbType.Int32, parameter.TipoDesconto.Codigo);
                }

                if (parameter.Percentual.HasValue)
                {
                    sql.AppendLine("AND PC_REDACR = :Percentual");
                    this.DataBase.AddInParameter(command, "Percentual", DbType.Decimal, parameter.Percentual);
                }

                command.CommandText = sql.ToString();

                listaDescontos = this.FindAll<BusinessEntity.DescontoDiferenciado>(command, reader => new BusinessEntity.DescontoDiferenciado
                {
                    CodigoTabela = (reader["Codigo"] != DBNull.Value ? reader.GetValue<int?>("Codigo") : null),
                    Percentual = (reader["Percentual"] != DBNull.Value ? reader.GetValue<decimal?>("Percentual") : null),
                    TipoDesconto = new BusinessEntity.TipoDescontoDiferenciado { Codigo = reader.GetValue<int>("CodigoTipoDesconto") }
                });
            }

            listaDescontos.ForEach(desconto => listaTiposDescontos.ForEach(tipo =>
                {
                    if (desconto.TipoDesconto.Codigo.Equals(tipo.Codigo))
                    {
                        desconto.TipoDesconto.Descricao = tipo.Descricao;
                        desconto.TipoDesconto.Obrigatorio = tipo.Obrigatorio;
                    }
                })
            );

            return listaDescontos;
        }

        #endregion

        #region DuplicarDescontosDiferenciados

        /// <summary>
        /// Duplica os descontos diferenciados baseado em uma tabela de corretagem
        /// </summary>
        /// <param name="tabelaOrigem">Tabela de Origem</param>
        /// <param name="tabelaDestino">Tabela de Destino</param>
        public void DuplicarDescontosDiferenciados(BusinessEntity.Parameter.FiltroTabelaCorretagemChave tabelaOrigem, BusinessEntity.Parameter.FiltroTabelaCorretagemChave tabelaDestino)
        {
            StringBuilder sql = new StringBuilder();

            sql.AppendLine("INSERT INTO TBOCORR_POLI_DESC(");
            sql.AppendLine("    CD_TABELA,");
            sql.AppendLine("    IN_TIPO_DESC,");
            sql.AppendLine("    PC_REDACR)");
            sql.AppendLine("SELECT :CodigoTabelaDestino,");
            sql.AppendLine("    IN_TIPO_DESC,");
            sql.AppendLine("    PC_REDACR ");
            sql.AppendLine("FROM");
            sql.AppendLine("    TBOCORR_POLI_DESC");
            sql.AppendLine("WHERE");
            sql.AppendLine("    CD_TABELA = :CodigoTabelaOrigem");

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sql.ToString()))
            {
                this.DataBase.AddInParameter(command, "CodigoTabelaDestino", DbType.Int32, tabelaDestino.Codigo);
                this.DataBase.AddInParameter(command, "CodigoTabelaOrigem", DbType.Int32, tabelaOrigem.Codigo);

                this.DataBase.ExecuteNonQuery(command);
            }
        }

        #endregion

        #region ExcluirDescontoDiferenciado

        /// <summary>
        /// Exclui do banco de dados um desconto diferenciado de uma tabela de corretagem
        /// </summary>
        /// <param name="parameter">Parâmetro para excluir do banco de dados um desconto diferenciado de uma tabela de corretagem</param>
        public void ExcluirDescontoDiferenciado(BusinessEntity.Parameter.FiltroDescontoDiferenciadoChave parameter)
        {
            StringBuilder sql = new StringBuilder();

            sql.AppendLine("DELETE FROM TBOCORR_POLI_DESC");
            sql.AppendLine("WHERE");
            sql.AppendLine("    CD_TABELA = :CodigoTabela");
            sql.AppendLine("    AND IN_TIPO_DESC = :CodigoTipoDesconto");

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sql.ToString()))
            {
                this.DataBase.AddInParameter(command, "CodigoTabela", DbType.Int32, parameter.CodigoTabela);
                this.DataBase.AddInParameter(command, "CodigoTipoDesconto", DbType.Int32, parameter.TipoDesconto.Codigo);

                this.DataBase.ExecuteNonQuery(command);
            }
        }

        #endregion

        #region ExcluirTodosDescontosDiferenciados

        /// <summary>
        /// Exclui todos os descontos diferenciados de uma tabela de corretagem.
        /// </summary>
        /// <Obs>
        /// Para exclusão de todos os descontos basta informar o codigo da tabela no filtro
        /// </Obs>
        /// <param name="parameter">Parâmetro para excluir todos os descontos diferenciados de uma tabela de corretagem</param>
        public void ExcluirTodosDescontosDiferenciados(BusinessEntity.Parameter.FiltroDescontoDiferenciadoChave parameter)
        {
            StringBuilder sql = new StringBuilder();

            sql.AppendLine("DELETE FROM TBOCORR_POLI_DESC");
            sql.AppendLine("WHERE");
            sql.AppendLine("    CD_TABELA = :CodigoTabela");

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sql.ToString()))
            {
                this.DataBase.AddInParameter(command, "CodigoTabela", DbType.Int32, parameter.CodigoTabela);

                this.DataBase.ExecuteNonQuery(command);
            }
        }

        #endregion

        #region IncluirDescontoDiferenciado

        /// <summary>
        /// Inclui no banco de dados um desconto diferenciado para uma tabela de corretagem
        /// </summary>
        /// <param name="entity">Parâmetro para incluir no banco de dados um desconto diferenciado para uma tabela de corretagem</param>
        public void IncluirDescontoDiferenciado(BusinessEntity.DescontoDiferenciado entity)
        {
            StringBuilder sql = new StringBuilder();

            sql.AppendLine("INSERT INTO TBOCORR_POLI_DESC(");
            sql.AppendLine("    CD_TABELA,");
            sql.AppendLine("    IN_TIPO_DESC,");
            sql.AppendLine("    PC_REDACR)");
            sql.AppendLine("VALUES(");
            sql.AppendLine("    :CodigoTabela,");
            sql.AppendLine("    :CodigoTipoDesconto,");
            sql.AppendLine("    :Percentual)");

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sql.ToString()))
            {
                this.DataBase.AddInParameter(command, "CodigoTabela", DbType.Int32, entity.CodigoTabela);
                this.DataBase.AddInParameter(command, "CodigoTipoDesconto", DbType.Int32, entity.TipoDesconto.Codigo);
                this.DataBase.AddInParameter(command, "Percentual", DbType.Decimal, entity.Percentual);

                this.DataBase.ExecuteNonQuery(command);
            }
        }

        #endregion
    }
}